package com.apimarket.service;

import com.apimarket.annotation.MultiDSTransactionalAnnotation;
import com.apimarket.dao.SysRoleMenuMapper;
import com.apimarket.dao.SysUserMapper;
import com.apimarket.dao.SysUserRoleMapper;
import com.apimarket.entity.SysMenu;
import com.apimarket.entity.SysUser;
import com.apimarket.entity.vo.JsonResult;
import com.apimarket.entity.vo.SysUserMenuVo;
import com.apimarket.enums.ExceptionEnum;
import com.apimarket.exception.AMException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.xml.rpc.ServiceException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author ZXR
 * @Date 2021/7/20 9:32
 * @Version 1.0
 */

@Service
public class SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;
    @Autowired
    private ConsumerService consumerService;
    //根据用户名查用户
    public SysUser selectByName(String username){
        SysUser sysUser = sysUserMapper.selectByName(username);
        return sysUser;
    }
    //根据用户名查用户全新啊信息
    public List<SysMenu> selectMenuListByUser(Integer userId){
        List<SysMenu> userMenuList=sysUserMapper.selectMenuListByUser(userId);
        return userMenuList;
    }

    public void update(SysUser sysUser) {
        if(sysUser.getId()==null)
            throw new AMException(ExceptionEnum.ID_IS_NULL);
        sysUserMapper.update(sysUser);
    }

    public List<SysMenu> selectMenuListByPath(String requestUrl) {
        List<SysMenu> list=sysUserMapper.selectMenuListByPath(requestUrl);
        return list;
    }

    public int saveObject(SysUser entity,Integer[] roleIds) throws IOException, URISyntaxException {
        long start=System.currentTimeMillis();
        //1.参数校验
        if (entity==null)
            throw new IllegalArgumentException("保存对象不能为空");
        if (entity.getUserName().isEmpty())
            throw new IllegalArgumentException("用户名不能为空");
        if (entity.getPassword().isEmpty())
            throw new IllegalArgumentException("密码不能为空");
        if (roleIds==null || roleIds.length==0)
            throw new IllegalArgumentException("至少要为用户分配角色");
        //2.保存用户自身信息
        //2.1对密码进行加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String processed_password=passwordEncoder.encode(entity.getPassword());
        entity.setPassword(processed_password);
        //3.保存用户角色关系数据
        //先插入kong的
        //外部人员在注册的时候会生成一个kong中的id
        //内部人员就直接数据库录入管理员的id
        String kongId=consumerService.addConsumer(entity.getUserName());
        //注册后为kong中的用户添加一个秘钥
        consumerService.generateKeyForConsumer(kongId);
        entity.setKongId(kongId);
        int rows=sysUserMapper.insertObject(entity);
        //用户角色
        sysUserRoleMapper.insertObjects(entity.getId(), roleIds);
        return rows;
    }

    public int deleteObject(String userName) throws IOException, URISyntaxException {
        if (userName==null )
            throw new IllegalArgumentException("请输入用户名");
        SysUser user=selectByName(userName);
        if (user==null)
            throw new IllegalArgumentException("不存在该用户");

        //Delete record in kong first
        consumerService.delConsumer(userName);
        //Then delete record in mysql
        sysUserMapper.deleteObject(userName);

        //删除用户角色
        sysUserRoleMapper.deleteObjectsByUserId(user.getId());

        //删除kong中
        consumerService.delConsumer(user.getKongId());


        return 0;
    }

    public void updateObject(SysUser entity, Integer[] roleIds) {

        //1.参数有效性验证
        if(entity==null)
            throw new IllegalArgumentException("保存对象不能为空");
        if(entity.getUserName().isEmpty())
            throw new IllegalArgumentException("用户名不能为空");
        if(roleIds==null||roleIds.length==0)
            throw new IllegalArgumentException("必须为其指定角色");
        entity.setUpdateTime(new Date());
        //密码可能改了
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String processed_password=passwordEncoder.encode(entity.getPassword());
        entity.setPassword(processed_password);
        sysUserMapper.updateObject(entity);
        SysUser sysUser=sysUserMapper.selectByName(entity.getUserName());
        sysUserRoleMapper.deleteObjectsByUserId(sysUser.getId());
        sysUserRoleMapper.insertObjects(sysUser.getId(), roleIds);
    }

    public int validById(Integer id,Integer enabled) throws ServiceException {
        //1.合法性验证
        if(id==null||id<=0)
            throw new ServiceException("参数不合法,id="+id);
        if(enabled==null||(enabled!=1&&enabled!=0))
            throw new ServiceException("参数不合法,enabled="+enabled);
        //2.执行禁用或启用操作(admin为后续登陆用户）
        int rows=sysUserMapper.validById(id, enabled);
        //3.判定结果,并返回
        if(rows==0)
            throw new ServiceException("此记录可能已经不存在");
        return rows;
    }

    //根据用户id查询他所有有权限的菜单
    public List<SysUserMenuVo> findUserMenusByUserId(Integer id){
        List<SysUserMenuVo> result=null;
        //基于用户id查找用户对应的角色id
        List<Integer> roleIds = sysUserRoleMapper.findRoleIdsByUserId(id);
        //基于角色id获取角色对应的菜单信息，并进行封装
        List<Integer> menuIds=null;
        if(roleIds!=null && roleIds.size()!=0) {
            menuIds = sysRoleMenuMapper.findMenuIdsByRoleIds(roleIds);
            if(menuIds!=null && menuIds.size()!=0)
                return sysUserMapper.findMenusByIds(menuIds);
        }
        return null;
    }

    public PageInfo<SysUser> findPageObjects(String username, Integer page,
                                             Integer pageSize) throws ServiceException {
        //1.对参数进行校验
        if(page==null||page<1)
            throw new IllegalArgumentException("当前页码值无效");
        //2.查询总记录数并进行校验
        int rowCount=sysUserMapper.getRowCount(username);
        if(rowCount==0)
            throw new ServiceException("没有找到对应记录");
        //3.查询当前页记录
        Integer startIndex=(page-1)*pageSize;
        PageHelper.startPage(page,pageSize);
        List<SysUser> records=sysUserMapper.findPageObjects(username);
        PageInfo<SysUser> pageInfo=new PageInfo<>(records);
        //4.对查询结果进行封装并返回
        return pageInfo;

    }

    public void UpdatePassword(String username,
                            String passwordA, String passwordB) throws ServiceException {
        if (!passwordA.equals(passwordB)){
            throw new ServiceException("两次密码不一致");
        }
        SysUser entity =selectByName(username);
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String processed_password=passwordEncoder.encode(passwordA);
        entity.setPassword(processed_password);
        sysUserMapper.updateObject(entity);
    }

    public void userRegister(String userName, String password, String email,
                             String telephone,boolean gender) throws IOException, URISyntaxException {
        //set
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String processed_password=passwordEncoder.encode(password);

        //
        Integer roleId=sysUserMapper.findRoleId("user");
        Integer[] roleIds={roleId};
        String kongId=consumerService.addConsumer(userName);
        consumerService.generateKeyForConsumer(kongId);
        SysUser entity=new SysUser(userName,processed_password,gender,telephone,email);
        entity.setKongId(kongId);
        int rows=sysUserMapper.insertObject(entity);
        //用户角色
        sysUserRoleMapper.insertObjects(entity.getId(), roleIds);
    }

    public boolean checkVerify(String checkCode, String random){
        if (random == null) {
            return false;
        }
        if (random.equals(checkCode)) {
            return true;
        } else {
            return false;

        }
    }

    //if user exist return false
    public boolean checkUserExist(String userName) {
        Integer res=sysUserMapper.checkUserExist(userName);
        if (res==null){
            return false;
        }
        else {
            return true;
        }
    }

    public List<SysUser> findUserByKongId(String id) {
        return sysUserMapper.findUserByKongId(id);
    }
}
